/*
 * Copyright © 2024-2025 Wenze Wei
 *
 * This file is part of StadionOS.
 *
 * This Source Code Form is subject to the terms of the GNU General Public License, v. 2.0.
 * You can obtain a copy of the GPL at
 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 */

#include "../include/errorr.h"

/**
 * @brief Prints an error message with a prefix.
 *
 * This function prints a user-defined string followed by a colon and a space,
 * and then calls Spperror to print the corresponding error message based on
 * the current error code retrieved by Sgetr().
 *
 * @param s The user-defined string to be printed before the error message.
 */
void Sperror(const char *s) {
    Sprint("%s: ", s);
    Spperror(Sgetr());
}

/**
 * @brief Prints the error message corresponding to an error code.
 *
 * This function takes an error code as input and prints the corresponding
 * error message. It uses a switch statement to match the error code with
 * the appropriate error message. If the error code does not match any case,
 * it prints "Unknown error".
 *
 * @param err The error code for which the error message is to be printed.
 */
void Spperror(int err) {
    switch (err) {
        case EEPERM:
            Sprint("Operation not permitted");
            break;
        case EENOENT:
            Sprint("No such file or directory");
            break;
        case EESRCH:
            Sprint("No such process");
            break;
        case EEINTR:
            Sprint("Interrupted system call");
            break;
        case EEIO:
            Sprint("Input/output error");
            break;
        case EENXIO:
            Sprint("No such device or address");
            break;
        case EE2BIG:
            Sprint("Argument list too long");
            break;
        case EENOEXEC:
            Sprint("Exec format error");
            break;
        case EEBADF:
            Sprint("Bad file descriptor");
            break;
        case EECHILD:
            Sprint("No child processes");
            break;
        case EEAGAIN:
            Sprint("Resource temporarily unavailable");
            break;
        case EENOMEM:
            Sprint("Cannot allocate memory");
            break;
        case EEACCES:
            Sprint("Permission denied");
            break;
        case EEFAULT:
            Sprint("Bad address");
            break;
        case EENOTBLK:
            Sprint("Block device required");
            break;
        case EEBUSY:
            Sprint("Device or resource busy");
            break;
        case EEEXIST:
            Sprint("File exists");
            break;
        case EEXDEV:
            Sprint("Invalid cross-device link");
            break;
        case EENODEV:
            Sprint("No such device");
            break;
        case EENOTDIR:
            Sprint("Not a directory");
            break;
        case EEISDIR:
            Sprint("Is a directory");
            break;
        case EEINVAL:
            Sprint("Invalid argument");
            break;
        case EENFILE:
            Sprint("Too many open files in system");
            break;
        case EEMFILE:
            Sprint("Too many open files");
            break;
        case EETXTBSY:
            Sprint("Text file busy");
            break;
        case EEFBIG:
            Sprint("File too large");
            break;
        case EENOSPC:
            Sprint("No space left on device");
            break;
        case EESPIPE:
            Sprint("Illegal seek");
            break;
        case EEROFS:
            Sprint("Read-only file system");
            break;
        case EEMLINK:
            Sprint("Too many links");
            break;
        case EEPIPE:
            Sprint("Broken pipe");
            break;
        case EEDOM:
            Sprint("Numerical argument out of domain");
            break;
        case EERANGE:
            Sprint("Numerical result out of range");
            break;
        case EEDEADLK:
            Sprint("Resource deadlock avoided");
            break;
        case EENAMETOOLONG:
            Sprint("File name too long");
            break;
        case EENOLCK:
            Sprint("No locks available");
            break;
        case EENOSYS:
            Sprint("Function not implemented");
            break;
        case EENOTEMPTY:
            Sprint("Directory not empty");
            break;
        case EELOOP:
            Sprint("Too many levels of symbolic links");
            break;
        case EEWOULDBLOCK:
            Sprint("Operation would block");
            break;
        case EENOMSG:
            Sprint("No message of desired type");
            break;
        case EEIDRM:
            Sprint("Identifier removed");
            break;
        case EECHRNG:
            Sprint("Channel number out of range");
            break;
        case EEL2NSYNC:
            Sprint("Level 2 not synchronized");
            break;
        case EEL3HLT:
            Sprint("Level 3 halted");
            break;
        case EEL3RST:
            Sprint("Level 3 reset");
            break;
        case EELNRNG:
            Sprint("Link number out of range");
            break;
        case EEUNATCH:
            Sprint("Protocol driver not attached");
            break;
        case EENOCSI:
            Sprint("No CSI structure available");
            break;
        case EEL2HLT:
            Sprint("Level 2 halted");
            break;
        case EEBADE:
            Sprint("Invalid exchange");
            break;
        case EEBADR:
            Sprint("Invalid request descriptor");
            break;
        case EEXFULL:
            Sprint("Exchange full");
            break;
        case EENOANO:
            Sprint("No anode");
            break;
        case EEBADRQC:
            Sprint("Invalid request code");
            break;
        case EEBADSLT:
            Sprint("Invalid slot");
            break;
        case EEDEADLOCK:
            Sprint("Resource deadlock avoided");
            break;
        case EEBFONT:
            Sprint("Bad font file format");
            break;
        case EENOSTR:
            Sprint("Device not a stream");
            break;
        case EENODATA:
            Sprint("No data available");
            break;
        case EETIME:
            Sprint("Timer expired");
            break;
        case EENOSR:
            Sprint("Out of streams resources");
            break;
        case EENONET:
            Sprint("Machine is not on the network");
            break;
        case EENOPKG:
            Sprint("Package not installed");
            break;
        case EEREMOTE:
            Sprint("Object is remote");
            break;
        case EENOLINK:
            Sprint("Link has been severed");
            break;
        case EEADV:
            Sprint("Advertise error");
            break;
        case EESRMNT:
            Sprint("Srmount error");
            break;
        case EECOMM:
            Sprint("Communication error on send");
            break;
        case EEPROTO:
            Sprint("Protocol error");
            break;
        case EEMULTIHOP:
            Sprint("Multihop attempted");
            break;
        case EEDOTDOT:
            Sprint("RFS specific error");
            break;
        case EEBADMSG:
            Sprint("Bad message");
            break;
        case EEOVERFLOW:
            Sprint("Value too large for defined data type");
            break;
        case EENOTUNIQ:
            Sprint("Name not unique on network");
            break;
        case EEBADFD:
            Sprint("File descriptor in bad state");
            break;
        case EEREMCHG:
            Sprint("Remote address changed");
            break;
        case EELIBACC:
            Sprint("Can not access a needed shared library");
            break;
        case EELIBBAD:
            Sprint("Accessing a corrupted shared library");
            break;
        case EELIBSCN:
            Sprint(".lib section in a.out corrupted");
            break;
        case EELIBMAX:
            Sprint("Attempting to link in too many shared libraries");
            break;
        case EELIBEXEC:
            Sprint("Cannot exec a shared library directly");
            break;
        case EEILSEQ:
            Sprint("Invalid or incomplete multibyte or wide character");
            break;
        case EERESTART:
            Sprint("Interrupted system call should be restarted");
            break;
        case EESTRPIPE:
            Sprint("Streams pipe error");
            break;
        case EEUSERS:
            Sprint("Too many users");
            break;
        case EENOTSOCK:
            Sprint("Socket operation on non-socket");
            break;
        case EEDESTADDRREQ:
            Sprint("Destination address required");
            break;
        case EEMSGSIZE:
            Sprint("Message too long");
            break;
        case EEPROTOTYPE:
            Sprint("Protocol wrong type for socket");
            break;
        case EENOPROTOOPT:
            Sprint("Protocol not available");
            break;
        case EEPROTONOSUPPORT:
            Sprint("Protocol not supported");
            break;
        case EESOCKTNOSUPPORT:
            Sprint("Socket type not supported");
            break;
        case EEOPNOTSUPP:
            Sprint("Operation not supported");
            break;
        case EEPFNOSUPPORT:
            Sprint("Protocol family not supported");
            break;
        case EEAFNOSUPPORT:
            Sprint("Address family not supported by protocol");
            break;
        case EEADDRINUSE:
            Sprint("Address already in use");
            break;
        case EEADDRNOTAVAIL:
            Sprint("Cannot assign requested address");
            break;
        case EENETDOWN:
            Sprint("Network is down");
            break;
        case EENETUNREACH:
            Sprint("Network is unreachable");
            break;
        case EENETRESET:
            Sprint("Network dropped connection on reset");
            break;
        case EECONNABORTED:
            Sprint("Software caused connection abort");
            break;
        case EECONNRESET:
            Sprint("Connection reset by peer");
            break;
        case EENOBUFS:
            Sprint("No buffer space available");
            break;
        case EEISCONN:
            Sprint("Transport endpoint is already connected");
            break;
        case EENOTCONN:
            Sprint("Transport endpoint is not connected");
            break;
        case EESHUTDOWN:
            Sprint("Cannot send after transport endpoint shutdown");
            break;
        case EETOOMANYREFS:
            Sprint("Too many references: cannot splice");
            break;
        case EETIMEDOUT:
            Sprint("Connection timed out");
            break;
        case EECONNREFUSED:
            Sprint("Connection refused");
            break;
        case EEHOSTDOWN:
            Sprint("Host is down");
            break;
        case EEHOSTUNREACH:
            Sprint("No route to host");
            break;
        case EEALREADY:
            Sprint("Operation already in progress");
            break;
        case EEINPROGRESS:
            Sprint("Operation now in progress");
            break;
        case EESTALE:
            Sprint("Stale file handle");
            break;
        case EEUCLEAN:
            Sprint("Structure needs cleaning");
            break;
        case EENOTNAM:
            Sprint("Not a XENIX named type file");
            break;
        case EENAVAIL:
            Sprint("No XENIX semaphores available");
            break;
        case EEISNAM:
            Sprint("Is a named type file");
            break;
        case EEREMOTEIO:
            Sprint("Remote I/O error");
            break;
        case EEDQUOT:
            Sprint("Disk quota exceeded");
            break;
        case EENOMEDIUM:
            Sprint("No medium found");
            break;
        case EEMEDIUMTYPE:
            Sprint("Wrong medium type");
            break;
        case EECANCELED:
            Sprint("Operation canceled");
            break;
        case EENOKEY:
            Sprint("Required key not available");
            break;
        case EEKEYEXPIRED:
            Sprint("Key has expired");
            break;
        case EEKEYREVOKED:
            Sprint("Key has been revoked");
            break;
        case EEKEYREJECTED:
            Sprint("Key was rejected by service");
            break;
        case EEOWNERDEAD:
            Sprint("Owner died");
            break;
        case EENOTRECOVERABLE:
            Sprint("State not recoverable");
            break;
	    case EBERROR:
	        exit(1);
	        break;
        case ERETAIN1:
            Sprint("Retain error");
            break;
        case ERETAIN2:
            Sprint("Retain error");
            break;
        case ERETAIN3:
            Sprint("Retain error");
            break;
        default:
            Sprint("Unknown error");
            break;
       }
}
